home *** CD-ROM | disk | FTP | other *** search
- #define LIBQTOOLS_CORE
- #include "../include/libqtools.h"
-
- /*
- * PAK-tools
- *
- * entryName == 0 -> OP_EXTRACT all
- * destDir == 0 -> OP_EXTRACT to current directory
- */
-
- /*
- *
- */
-
- bool CheckPAK(FILE * pakFile, struct packheader *Header, bool newWad)
- {
- if (pakFile) {
- fseek(pakFile, 0, SEEK_END);
- if (ftell(pakFile) == 0) {
- if (newWad == TRUE) {
- /*
- * file is new
- */
- Header->magic.integer = MAGIC_PACK;
- Header->offset = LittleLong(sizeof(struct packheader));
- Header->size = LittleLong(0);
- fwrite(Header, 1, sizeof(struct packheader), pakFile);
- return TRUE;
- }
- else
- return FALSE;
- }
- else {
- fseek(pakFile, 0, SEEK_SET);
- fread(Header, 1, sizeof(struct packheader), pakFile);
-
- if (Header->magic.integer == MAGIC_PACK) {
- /*
- * file is not a packfile
- */
- return TRUE;
- }
- else
- return FALSE;
- }
- }
- else
- return FALSE;
- }
-
- /*
- * findpak return ever one entry more than exists!
- */
- struct packentry *FindPAK(FILE * pakFile, char *entryName, struct packheader *Header, struct packentry **Entry)
- {
- struct packentry *allEntries;
-
- fseek(pakFile, LittleLong(Header->offset), SEEK_SET);
- if ((*Entry = allEntries = (struct packentry *)tmalloc(LittleLong(Header->size) + sizeof(struct packentry)))) {
- int i;
-
- fread(allEntries, 1, LittleLong(Header->size), pakFile);
- if (entryName) {
- for (i = 0; i < (LittleLong(Header->size) / sizeof(struct packentry)); i++) {
- if (!strncasecmp(entryName, allEntries->name, NAMELEN_PAK)) {
- /*
- * return offset of valid entry
- */
- return allEntries;
- }
- allEntries++;
- }
- }
- /*
- * not in pakfile
- */
- return 0;
- }
- else
- return (struct packentry *)-1;
- }
-
- struct packentry *SearchPAK(char *entryName, struct packheader *Header, struct packentry *allEntries) {
- int i;
-
- for (i = 0; i < (LittleLong(Header->size) / sizeof(struct packentry)); i++) {
- if (!strncasecmp(entryName, allEntries->name, NAMELEN_PAK))
- return allEntries;
- allEntries++;
- }
- return 0;
- }
-
- bool ExtractPAK(FILE * pakFile, FILE * script, char *destDir, char *entryName, unsigned char outType, operation procOper, bool recurse)
- {
- struct packheader Header;
- struct packentry *Entry, *allEntries;
- bool retval = FALSE;
-
- if (CheckPAK(pakFile, &Header, FALSE) == TRUE) {
- /*
- * we assume that the dir is at the end of the file!!!!!
- */
- switch ((int)(Entry = FindPAK(pakFile, entryName, &Header, &allEntries))) {
- case -1:
- eprintf("cannot tmalloc memory for all entries of size %ld\n", LittleLong(Header.size) + sizeof(struct packentry));
- break;
- case 0:
- if((entryName) && (*entryName != '\0')) {
- eprintf("no entry %s found in pak\n", entryName);
- break;
- }
- default:{
- int i = 0;
-
- /*
- * process only ONE (case 0:)
- */
- if (Entry)
- i = (LittleLong(Header.size) / sizeof(struct packentry)) - 1;
- /*
- * reset and process ALL (default:)
- */
- else
- Entry = allEntries;
-
- for (; i < (LittleLong(Header.size) / sizeof(struct packentry)); i++) {
- char fileName[NAMELEN_PATH];
-
- strncpy(fileName, destDir, NAMELEN_PATH - 1);
- strncat(fileName, Entry->name, NAMELEN_PATH - 1);
-
- switch (procOper) {
- case OP_EXTRACT:{
- FILE *fileDst;
-
- mprintf("extract %s ...\n", Entry->name);
- CreatePath(fileName);
-
- if ((fileDst = fopen(fileName, WRITE_BINARY))) {
- struct rawdata *rawData;
-
- fseek(pakFile, LittleLong(Entry->offset), SEEK_SET);
- if ((rawData = GetRaw(pakFile, Entry->name, LittleLong(Entry->size)))) {
- retval = PutRaw(fileDst, rawData);
- rfree(rawData);
- /*
- * processName at this point
- */
- if (recurse == TRUE)
- retval = processName(fileName, 0, 0, outType, 0, 0, procOper, script ? TRUE : FALSE, recurse);
- }
- else
- eprintf("cannot tmalloc memory for %s of size %d\n", fileName, LittleLong(Entry->size));
- fclose(fileDst);
- }
- else
- eprintf("cannot open %s\n", fileName);
- }
- break;
- case OP_LIST:
- case OP_DEFAULT:
- default:{
- mprintf("%54s %8d bytes (offset: %8x)\n", Entry->name, LittleLong(Entry->size), LittleLong(Entry->offset));
- retval = TRUE;
- }
- break;
- }
- if (script)
- fprintf(script, "update %s as %s as %c\n", fileName, Entry->name, 'P');
- Entry++;
- }
- }
- break;
- }
- tfree(allEntries);
- }
- else
- eprintf("no valid pakfile\n");
-
- return retval;
- }
-
- bool AddPAK(struct palpic *inPic, struct rawdata * inData, char *pakName, operation procOper)
- {
- char *procName;
- FILE *pakFile = fopen(pakName, READWRITE_BINARY_OLD);
- struct packheader Header;
- struct packentry *Entry, *allEntries;
- bool retval = FALSE;
-
- if (!pakFile)
- pakFile = fopen(pakName, READWRITE_BINARY_NEW);
-
- if (pakFile) {
- if (CheckPAK(pakFile, &Header, TRUE) == TRUE) {
- if (inPic) {
- procName = inPic->name;
- ReplaceExt(procName, "lmp");
- }
- else if (inData) {
- procName = inData->name;
- }
- /*
- * we assume that the dir is at the end of the file!!!!!
- */
- switch ((int)(Entry = FindPAK(pakFile, procName, &Header, &allEntries))) {
- case -1:
- eprintf("cannot tmalloc memory for all entries of size %ld\n", LittleLong(Header.size) + sizeof(struct packentry));
- break;
- case 0:
- switch (procOper) {
- case OP_REPLACE:
- eprintf("no entry %s found to replace in pak %s\n", procName, pakName);
- break;
- case OP_ADD:
- case OP_UPDATE:
- case OP_DEFAULT:
- default:
- fseek(pakFile, LittleLong(Header.offset), SEEK_SET);
- /*
- * seek to end of data
- */
- Entry = allEntries + (LittleLong(Header.size) / sizeof(struct packentry));
- Entry->offset = Header.offset;
-
- if (inData)
- retval = PutRaw(pakFile, inData);
- else if (inPic)
- retval = PutLMP(pakFile, inPic);
- else
- eprintf("nothing to add\n");
-
- if(retval == TRUE) {
- Entry->size = LittleLong(ftell(pakFile) - LittleLong(Header.offset));
- strncpy(Entry->name, procName, NAMELEN_PAK);
- Header.size = LittleLong(LittleLong(Header.size) + sizeof(struct packentry));
- Header.offset = LittleLong(ftell(pakFile));
- /*
- * write directory
- */
- if(fwrite(allEntries, 1, LittleLong(Header.size), pakFile) == LittleLong(Header.size)) {
- fseek(pakFile, 0, SEEK_SET);
- /*
- * write header
- */
- fwrite(&Header, 1, sizeof(struct packheader), pakFile);
- fflush(pakFile);
- }
- else
- retval = FALSE;
- }
- else
- eprintf("cannot write data %s to pak %s\n", procName, pakName);
- break;
- }
- tfree(allEntries);
- break;
- default:
- switch (procOper) {
- case OP_REPLACE:
- case OP_UPDATE:
- /* DeletePAK() */
- /* AddPAK() */
- retval = TRUE;
- break;
- case OP_ADD:
- case OP_DEFAULT:
- default:
- eprintf("old entry %s found in pak %s\n", procName, pakName);
- break;
- }
- tfree(allEntries);
- break;
- }
- fclose(pakFile);
- }
- else
- eprintf("no valid pakfile %s\n", pakName);
- }
- else
- eprintf("cannot open desired pakfile %s\n", pakName);
-
- return retval;
- }
-